#pragma once

namespace BlackDeath
{
	namespace Core
	{
		class CGameWindow;
		class CGame;
	}

	namespace Graphics
	{
		class CVertexBuffer;
		class CIndexBuffer;
		class CMesh;

		class CGraphicsDevice
		{
			private:
			#pragma region Variables
				bool m_bFullScreen;
				ID3D10Device* m_pGraphicsDevice;
				IDXGISwapChain* m_pSwapChain;
				ID3D10RenderTargetView* m_pCurrRenderTarget;
				ID3D10DepthStencilView* m_pDepthStencilView;
				ID3D10RasterizerState* m_pRenderState;
				ID3D10BlendState* m_pBlendState;
				ID3D10Texture2D* m_pDepthStencilBuffer;
				D3D10_VIEWPORT* m_pViewport;
				D3D10_INPUT_ELEMENT_DESC* m_pCurrVertexDeclaration;
				int m_iVertexDeclarationElements;
				BlackDeath::Core::CGameWindow* m_pWindow;
				BlackDeath::Graphics::CVertexBuffer* m_pCurrBuffer;
				BlackDeath::Graphics::CIndexBuffer* m_pIndexBuffer;
			#pragma endregion

			#pragma region Constructors and Destructors
				CGraphicsDevice(BlackDeath::Core::CGameWindow*);
				virtual ~CGraphicsDevice();
			#pragma endregion

			#pragma region Methods
				void Create();
				void Destroy();
				void CreateDevice(UINT width, UINT height);
				void CreateBackBuffer();
				void CreateDepthStencil(UINT width, UINT height);
				void CreateRenderState();
				void CreateBlendState();
			#pragma endregion

			public:
			#pragma region Options
				void ToggleFullscreen();
				void SetResolution(UINT, UINT);
				void SetViewport(UINT, UINT, UINT, UINT, float, float);
				void Resize(UINT width, UINT height);
			#pragma endregion

			#pragma region Properties
				D3D10_VIEWPORT* Get_Viewport();

				bool Get_IsFullscreen();

				void Set_VertexBuffer(CVertexBuffer*);

				void Set_Indices(CIndexBuffer*);

				void Set_VertexDeclaration(D3D10_INPUT_ELEMENT_DESC*, int);

				void Set_RenderState(D3D10_RASTERIZER_DESC*);

				void Set_BlendState(D3D10_BLEND_DESC*);

				ID3D10Device* Get_GraphicsDevice();
				#pragma endregion

			#pragma region More_Options
				void Clear(D3DXCOLOR);

				void Present();

				void DrawPrimitives(D3D10_PRIMITIVE_TOPOLOGY, int, int);

				void DrawIndexedPrimitives(D3D10_PRIMITIVE_TOPOLOGY, int, int, int, int, int);
			#pragma endregion

				friend class BlackDeath::Core::CGame;
			//TODO: friend class CSpriteBatch;
			friend class CVertexBuffer;
			friend class CIndexBuffer;
			//TODO: friend class CEffect;
			//TODO: friend class CTexture2D;
			//TODO: friend class CMesh;
		};
	}
}